package com.zerui.manager.app.device.executer;

import com.alibaba.cola.catchlog.CatchAndLog;
import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zerui.cola.dto.Response;
import com.zerui.manager.accessauthdevice.AccessAuthDevice;
import com.zerui.manager.accessauthdevice.gateway.AccessAuthDeviceGateWay;
import com.zerui.manager.device.Device;
import com.zerui.manager.device.custom.DeviceCustom;
import com.zerui.manager.device.gateway.DeviceGateWay;
import com.zerui.manager.operationrecord.OperationRecord;
import com.zerui.manager.operationrecord.gateway.OperationRecordGateWay;
import com.zerui.manager.web.cmd.DeviceOperateDoorCmd;
import com.zerui.manager.web.enums.DeviceFromEnum;
import com.zerui.manager.web.enums.DeviceOperateEnum;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author wh
 * @create_time 2023-08-25 14:31
 */
@Component
@CatchAndLog
public class DeviceOperateDoorCmdExe {

    @Resource
    private DeviceGateWay deviceGateWay;
    @Resource
    private AccessAuthDeviceGateWay accessAuthDeviceGateWay;
    @Resource
    private OperationRecordGateWay operationRecordGateWay;

    public Response execute(DeviceOperateDoorCmd deviceOperateDoorCmd) {
        List<DeviceCustom> devices = deviceGateWay.selectByDeviceIds2(deviceOperateDoorCmd.getDeviceIds());
        if(CollectionUtils.isEmpty(devices)){
            throw new BizException("设备不存在");
        }

        List<Device> filterList = devices.stream().filter(e -> e.getEnableStatus().equals(1)).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(filterList)){
            throw new BizException("存在设备被禁用，请启用后操作");
        }

        // 构建执行命令
        final String opearate = deviceOperateDoorCmd.getOperate();
        String command = DeviceOperateEnum.getActionByCode(deviceOperateDoorCmd.getOperate());
        if (StringUtils.isBlank(command)) {
            throw new BizException("指令不存在");
        }
        deviceOperateDoorCmd.setOperate(command);

        // IoT门禁命令下发
        List<DeviceCustom> iotDevices = devices.stream().filter(c -> c.getDeviceFrom().equals(DeviceFromEnum.FROM_IOT.getCode())).collect(Collectors.toList());
        if (!iotDevices.isEmpty()) {
            deviceOperateDoorCmd.setDeviceIds(iotDevices.stream().map(DeviceCustom::getDeviceId).collect(Collectors.toSet()));
            deviceGateWay.invokeIoTCommandBatch(deviceOperateDoorCmd); // 调用IoT命令操作
            addOperationRecord(iotDevices, opearate, deviceOperateDoorCmd.getIp());
        }

        // ICC门禁命令下发
        List<DeviceCustom> iccDevices = devices.stream().filter(c -> c.getDeviceFrom().equals(DeviceFromEnum.FROM_ICC.getCode())).collect(Collectors.toList());
        if (!iccDevices.isEmpty()) {
            deviceOperateDoorCmd.setDeviceIds(iccDevices.stream().map(DeviceCustom::getDeviceId).collect(Collectors.toSet()));
            deviceGateWay.invokeICCCommandBatch(deviceOperateDoorCmd); // 调用ICC命令操作
            addOperationRecord(iccDevices, opearate, deviceOperateDoorCmd.getIp());
        }
        return Response.buildSuccess();
    }

    private void addOperationRecord(List<DeviceCustom> devices, String operate, String ip) {
        DeviceOperateEnum operateEnum = DeviceOperateEnum.getDeviceOperateEnum(operate);
	    assert operateEnum != null;
	    String operateEnumName = operateEnum.getName();
        List<OperationRecord> operationRecords = new ArrayList<>();
        List<Long> deviceIds = devices.stream()
                .map(Device::getDeviceId)
                .collect(Collectors.toList());
        List<AccessAuthDevice> deviceInfo = accessAuthDeviceGateWay.getByDeviceIds(deviceIds);

        deviceInfo.forEach(e-> operationRecords.add(OperationRecord.builder()
                .deviceId(e.getDeviceId())
                .name(e.getDeviceName())
                .code(e.getDeviceCode())
                .opener(operateEnumName)
                .position(e.getPosition())
                .type(e.getTypeName())
                .ip(ip)
                .build()));
        operationRecordGateWay.insertBatch(operationRecords);


    }
}
